<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2019/3/27
 * Time: 22:50
 */

namespace App\Services;

use App\Library\Common;
use App\Models\Loss;
use App\Models\Order;
use App\Models\Shipping;
use App\Models\ShippingPay;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Validator;
use DB;

class ShippingService extends BaseService
{
    /**
     * 支付信息费成功后，往v_shipping表插入一条记录
     * @param array $data
     * @return array
     */
    public function createShipping(array $data)
    {
        $code = 0;
        $msg  = '操作成功';

        DB::beginTransaction();
        try {
            $validator = Validator::make($data, [
                'driver_uuid' => 'required',
                'order_id'    => 'required',
                'msg_fee_id'  => 'required'
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }
            $shipping = Shipping::onWriteConnection()
                ->where('order_id', $data['order_id'])
                ->where('msg_fee_id', $data['msg_fee_id'])
                ->where('driver_uuid', $data['driver_uuid'])
                ->first();
            if (!empty($shipping)) {
                return compact('code', 'msg'); //运单已经存在
            }

            $order = Order::findOrFail($data['order_id']);

            $data['shipping_no'] = Common::createShippingNo();
            $data['status']      = Shipping::$statusInfoPayComplete;
            Shipping::create($data);

            // 订单表更新
            $num = $order->shipping_car_num + 1;
            $order->shipping_car_num = $num;
            if ($num == $order->total_car_num) {
                $order->status = Order::STATUS_FINISH;
            }
            $order->save();

            DB::commit();

            return compact('code', 'msg');
        } catch (ModelNotFoundException $e) {
            DB::rollback();

            $code = 1;
            $msg  = Common::notFoundModelFormat($e->getModel());
            return compact('code', 'msg');
        } catch (\Exception $e) {
            DB::rollback();

            $code = 1;
            $msg  = $e->getMessage();
            return compact('code', 'msg');
        }
    }

    /**
     * 计算运单扣损
     * @param $shippingNo
     * @param $lossTotalNum
     * @return array
     */
    public function calculateShippingLossFee($shippingNo, $lossTotalNum = 0)
    {
        $shipping     = Shipping::where('shipping_no', $shippingNo)->firstOrFail();
        $order        = Order::findOrFail($shipping->order_id);
        $lossTotalNum = $lossTotalNum > 0 ? $lossTotalNum : $shipping->load_num - $shipping->unload_num; //不传递时直接计算
        $lossTotalNum = $lossTotalNum < 0 ? 0 : $lossTotalNum; //损耗只会大于大于0

        // 记录扣损信息
        $data = [
            'loss_total_num' => $lossTotalNum,
            'loss_num'       => 0,
            'loss_amount'    => 0,
        ];
        if (($lossTotalNum > $order->loss_limit) && ($order->loss_deduct == Order::LOSS_DEDUCT_Y)) {
            $lossNum             = $lossTotalNum - $order->loss_limit;
            $data['loss_num']    = $lossNum;
            $data['loss_amount'] = $lossNum * ($order->loss_price / 100); //单位统一
        }

        return $data;
    }

    /**
     * 计算运单金额
     * @param $shippingNo
     * @return array
     */
    public function calculateShippingAmount($shippingNo)
    {
        $shipping = Shipping::where('shipping_no', $shippingNo)->firstOrFail();
        $order    = Order::findOrFail($shipping->order_id);
        $loss     = Loss::where('shipping_id', $shipping->id)->firstOrFail();

        // 记录支付信息
        $lossAmount = $shipping->unload_num * ($order->price / 100);
        $data       = [
            'load_num'      => $shipping->unload_num,
            'load_amount'   => $lossAmount,
            'loss_amount'   => $loss->loss_amount,
            'actual_amount' => $lossAmount - $loss->loss_amount,
        ];

        return $data;
    }

    /**
     * 保存缺损信息
     * @param $shippingNo
     * @param $lossTotalNum
     * @param string $remark
     * @return bool
     * @throws \Exception
     */
    public function saveShippingLossFee($shippingNo, $lossTotalNum, $remark = '')
    {
        $shipping = Shipping::where('shipping_no', $shippingNo)->firstOrFail();
        if ($shipping->global_status != Shipping::GLOBAL_DRIVER_UNLOADED) {
            throw new \Exception('司机还未完成卸货磅单上传');
        }

        $lossData = $this->calculateShippingLossFee($shippingNo, $lossTotalNum);
        $lossData['shipping_id'] = $shipping->id;
        Loss::create($lossData);

        // 更新货运表
        $shipping->global_status  = Shipping::GLOBAL_RECEIVER_CONFIRM_LOSS;
        if (!empty($remark)) $shipping->deliver_remark = $remark;
        //$shipping->status         = Shipping::$statusUnLoadComplete; //确定金额后才修改状态
        $shipping->save();

        return true;
    }

    /**
     * 货主/收货人 确定结算金额
     * @param $shippingNo
     * @return bool
     */
    public function saveShippingAmount($shippingNo)
    {
        $shipping = Shipping::where('shipping_no', $shippingNo)->firstOrFail();

        $amountData = $this->calculateShippingAmount($shippingNo);
        $amountData['shipping_id'] = $shipping->id;
        ShippingPay::create($amountData);

        // 支付状态变更
        $shipping->global_status = Shipping::GLOBAL_OWNER_CONFIRM_AMOUNT;
        $shipping->pay_status    = Shipping::PAY_DONE;
        $shipping->status        = Shipping::$statusUnLoadComplete;
        $shipping->save();

        return true;
    }

}